/*********************************************
 All command related functions are handled here
**********************************************/
using namespace std;

bool integer(string name, int count);
bool type(string line);
bool typed_attribute_list(vector<string> line, int count);
bool delete_cmd(vector<string> line);
bool update_cmd(vector<string> line);
bool insert_cmd(vector<string> line);
bool create_cmd(vector<string> line);
bool show_cmd(vector<string> line);
bool exit_cmd(vector<string> line);
bool write_cmd(vector<string> line);
bool close_cmd(vector<string> line);
bool open_cmd(vector<string> line);

bool command(vector<string> line)
{
	if(open_cmd(line) || close_cmd(line) || write_cmd(line) || exit_cmd(line) || show_cmd(line) || create_cmd(line) || update_cmd(line) || insert_cmd(line) || delete_cmd(line))
	{
		return true;
	}
	return false;
}

//-------- open_cmd -------------

bool open_cmd(vector<string> line)
{
	if(line[0] == "open" || line[0] == "OPEN")
	{
		if(relation_name(line[1]))
		{
			return true;
		}
		else
		{
			//wrong relation name
		}
	}
	else
	{
		return false;
	}
}
//-------- clse_cmd -------------

bool close_cmd(vector<string> line)
{
	if(line[0] == "close" || line[0] == "CLOSE")
	{
		if(relation_name(line[1]))
		{
			return true;
		}
		else
		{
			//wrong relation name
		}
	}
	else
	{
		return false;
	}
}	
//-------- write_cmd -------------

bool write_cmd(vector<string> line)
{
	if(line[0] == "write" || line[0] == "WRITE")
	{
		if(relation_name(line[1]))
			{
				return true;
			}
		else
			{
				//wrong relation name
			}
	}
	else
	{
		return false;
	}
}
//-------- exit_cmd -------------

bool exit_cmd(vector<string> line)
{
	if(line[0] == "exit" || line[0] == "EXIT")
	{
		return true;
	}
	return false; // can't exit
}
//-------- show_cmd -------------

bool show_cmd(vector<string> line)
{
	if(line[0] == "show" || line[0] == "SHOW")
	{
		line.erase(line.begin(), line.begin()+1);
		if(atomic_expr(line))
		{
			return true;
		}
		else
		{
			//wrong relation name
		}
	}
	else
	{
		return false;
	}
}

//-------- create_cmd -------------

bool create_cmd(vector<string> line)
{
int i = 0;
int count = 0;
	if(line[0] == "create" || line[0] == "CREATE")
	{
		if(line[1] == "TABLE" || line[1] == "table")
		{
			if(relation_name(line[2]) && line[3] == "(")
			{
				line.erase(line.begin(), line.begin()+4);
				while(i < line.size())
				{
					if(line[i]==")")
					{
						count=i;
						break;
					}
					i++;
				}
				if(count == 0)
				{
					return false;//no table
				}
				if(typed_attribute_list(line,count))
				{

					line.erase(line.begin(), line.begin()+count+1);
		
					if(line[0] == "PRIMARY" || line[0] == "primary")
					{

						if(line[1] == "key" && line[2] == "(" || line[1] == "KEY" && line[2] == "(" )
						{

							line.erase(line.begin(), line.begin()+3);

							i=0;

							while(i < line.size())
							{
								if(line[i]==")")
								{
									count=i;
									break;
								}
								i++;
							}

							if(count == 0)
							{
								return false;//no table
							}

							if(attribute_list(line,count-1))
							{
								return true;
							}
							else
							{
								return false;//error attribute_lise
							}
							
						}
						else
						{
							return false;//no key
						}
					}
					else
					{
						return false;//no primary
					}
					
					
				}
				else
				{
					return false;//wrong attribute list
				}
			
			}
			else
			{
				return false;//wrong relation name, and no quotation
			}
		}
		else
		{
			return false;//wrong table
		}
	}
	else
	{
		return false;
	}
}

//-------- update_cmd -------------

bool update_cmd(vector<string> line)
{
int i = 3;
int count = 0;
	if(line[0] == "update" || line[0] == "UPDATE")
	{
		if(relation_name(line[1]))
		{
			if(line[2] == "set" || line[2] == "SET")
			{
				line.erase(line.begin(), (line.begin()+3));
				while(i < line.size())
				{
					//cheack for a Literal relation_name or an =
					if(relation_name(line[i]) && line[i+1] == "=" && Literal(line[i+2]) )
					{
						i=i+3;
					}
					else
					{
						count = i;
						break;
					}
				}
				if(count == 0)
				{
					return false;
					//something is wrong or no table for update
				}
				line.erase(line.begin(), line.begin()+count);
				if(line[0] == "where" ||line[0] == "WHERE" )
				{
					line.erase(line.begin(), line.begin()+1);
					if(conjunction(line,line.size()))
					{
						return true;
					}
					else
					{
						return false;
						//something wrong with the condition
					}
				}
				else
				{
					return false;
					//no where string
				}
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}

//-------- insert_cmd -------------

bool insert_cmd(vector<string> line)
{
//INSERT INTO relation-name VALUES FROM
int i = 0;
int count = 0;

//line.erase(line.end()-1);
	if(line[0] == "insert" || line[0] == "INSERT")
	{
		if(line[1] == "into" || line[1] == "INTO")
		{
			if(relation_name(line[2]))
			{
				if(line[3] == "VALUES" || line[3] == "values")
				{
					if(line[4] == "from" || line[4] == "FROM")
					{
						if(line[5] == "RELATION" || line[5] == "relation" || line[5] == "(") 
						{
							if(line[5] == "(")
							{
								line.erase(line.begin(), line.begin()+6);
								while(i < line.size())
								{
									if(line[i]==")")
									{
										count=i;
										break;
									}
									i++;
								} 
								if(count == 0)
								{
									return false;
									//no table
								}
								for(i = 0; i < count; i++)
								{
									if(!operand(line[i]))
									{
										return false;//something wrong with Literals
									}
								}
								return true;
							}
							else
							{
								line.erase(line.begin(), line.begin()+6);
								line.insert(line.begin(), "#");
								if(expr(line))
								{
									return true;
								}
								else
								{
									return false;
									//something wrong with expression
								}
							}
						}
						else
						{
							return false;
							//no relation or (
						}
					}
					else
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
				//wrong relation name
			}
		}
		else
		{
			return false;//wrong into
		}
		
	}
	else
	{
		return false;
	}
}

//-------- delte_cmd -------------

bool delete_cmd(vector<string> line)
{
//DELETE FROM relation-name WHERE condition
	if(line[0] == "delete" || line[0] == "DELETE")
	{
		if(line[1] == "FROM" || line[1] == "from")
		{
			if(relation_name(line[2]))
			{
				if(line[3] == "WHERE" && line[4] == "(" || line[3] == "where" && line[4] == "(")
				{
					line.erase(line.begin(), line.begin()+5);
					if(conjunction(line,line.size() - 1))
					{
						return true;
					}
					else
					{
						return false;//wrong condition
					}
				}
				else
				{
					return false;//wrong string
				}
			}
			else
			{
				return false;//wrong relation name
			}
		}
		else
		{
		
			return false;//wrong string
		}
	} 
	else
	{
		return false;//wrong string
	}
}


//-------- type_attribute_list -------------

bool typed_attribute_list(vector<string> line, int count)
{
	for(int i = 0; i < count; i= i + 2)
	{
		if(!relation_name(line[i])&&!type(line[i+1]))// atribute name
		{
			return false;
		}
	}
	return true;
}

//-------- type -------------

bool type(string line)
{
	string variance_character = "VARCHARvarchar";
	int i = 0;
	int count;
	if(line == "integer" || line == "INTEGER")
	{
		return true;
	}
	while(i < 7)
	{
		if(variance_character[i] != line[i] && variance_character[i+7] != line[i])
		{
			//error varchar is spelled wrong
			return false;
		}
	}
	if(line[7] == '(')
	line.erase(line.begin(), line.begin()+8);
	i=0;
	while(line[i] < line.size())
	{
		if(line[i]==')')
		{
			count=i;
			break;
		}
		i++;
	}
	if(count == 0)
	{
		return false;//no table
	}
	if(integer(line, count))
	{
		return true;
	}
	else
	{
		return false;// no integer
	}
	
}

//-------- integer -------------

bool integer(string name, int count)
{
	for(int i = 0; i < count; i++)
	{	
		if(!isdigit(name[i]))
		{
			return false;
		}
	}
	return true;
}
